package com.livepan.server.service.impl;


import com.livepan.server.dao.ProblemDOMapper;
import com.livepan.server.dataobject.ProblemDOKey;
import com.livepan.server.dataobject.ProblemDOWithBLOBs;
import com.livepan.server.error.BusinessException;
import com.livepan.server.error.EmBusinessError;
import com.livepan.server.service.ProblemService;
import com.livepan.server.service.model.ProblemModel;
import com.livepan.server.validator.ValidationResult;
import com.livepan.server.validator.ValidatorImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProblemServiceImpl implements ProblemService {
    @Resource
    private ProblemDOMapper problemDOMapper;

    @Autowired
    private ValidatorImpl validator;

    public ProblemModel getProblemByID(Integer problemId) {
        ProblemDOKey problemDOKey = new ProblemDOKey();
        problemDOKey.setProblemId(problemId);
        ProblemDOWithBLOBs problemDOWithBLOBs = problemDOMapper.selectByPrimaryKey(problemDOKey);

        return convertProblemModelFromProblemDO(problemDOWithBLOBs);
    }

    @Override
    public List<ProblemModel> listProblem(String keyword, int offset, int limit, String userId) {
        List<ProblemDOWithBLOBs> problemDOWithBLOBsList =
                problemDOMapper.queryProblemList(keyword, -1, offset, limit);
        List<ProblemModel> problemModelList = problemDOWithBLOBsList.stream()
                .map(this::convertProblemModelFromProblemDO).collect(Collectors.toList());
        return problemModelList;

    }


    @Override
    public ProblemModel createProblem(ProblemModel problemModel) throws BusinessException {

        ValidationResult validateResult = validator.validate(problemModel);
        if (validateResult.isHasError()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, validateResult.getErrMsg());
        }

        if (problemModel.getProblemId() == -1) {
            problemModel.setProblemId(null);
        }
        int i = problemDOMapper.insertSelective(convertProblemDOFromProblemModel(problemModel));
        if (i > 0) {
            return getProblemByID(problemModel.getProblemId());
        } else {
            throw new BusinessException(EmBusinessError.QUESTION_CREATE_ERROR);
        }

    }

    @Override
    public ProblemModel updateProblem(ProblemModel problemModel) throws BusinessException {
        ValidationResult validateResult = validator.validate(problemModel);
        if (validateResult.isHasError()) {
            throw new BusinessException(EmBusinessError.PARAMETER_VALIDATION_ERROR, validateResult.getErrMsg());
        }

        int i = problemDOMapper.updateByPrimaryKeySelective(convertProblemDOFromProblemModel(problemModel));
        if (i > 0) {
            return getProblemByID(problemModel.getProblemId());
        } else {
            throw new BusinessException(EmBusinessError.QUESTION_UPDATE_ERROR);
        }
    }

    @Override
    public Integer queryProblemCount(String keyword, Integer contestId) {
        Integer count = problemDOMapper.queryProblemCount(keyword, contestId);
        return count;
    }


    @Override
    @Transactional
    public Boolean addSubmitCount(Integer problemId, Integer contestId, @NotNull Integer value) {
        //更新了，就返回true
        return problemDOMapper.addSubmissionCount(problemId, contestId, value) > 0;
    }

    @Override
    @Transactional
    public Boolean addAcceptedCount(Integer problemId, Integer contestId,@NotNull Integer value) {
        //更新了，就返回true
        return problemDOMapper.addAcceptedCount(problemId, contestId, value) > 0;
    }


    private ProblemModel convertProblemModelFromProblemDO(ProblemDOWithBLOBs problemDOWithBLOBs) {
        if (problemDOWithBLOBs == null) {
            return null;
        }
        ProblemModel problemModel = new ProblemModel();
        BeanUtils.copyProperties(problemDOWithBLOBs, problemModel);
        problemModel.setSpj(problemDOWithBLOBs.getIsSpj());
        return problemModel;
    }

    private ProblemDOWithBLOBs convertProblemDOFromProblemModel(ProblemModel problemModel) {
        if (problemModel == null) {
            return null;
        }
        ProblemDOWithBLOBs problemDOWithBLOBs = new ProblemDOWithBLOBs();
        BeanUtils.copyProperties(problemModel, problemDOWithBLOBs);
        problemDOWithBLOBs.setIsSpj(problemModel.getSpj());
        return problemDOWithBLOBs;
    }
}
